home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Report Writers / Crystal Repot 9.0 Full CD version / Setup.exe / SRC / HOARDDLL.ZIP / 3rdParty / hoard / libhoard-2.0.2 / arch-specific-win32.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-06-18  |  6.3 KB  |  246 lines

  1. ///-*-C++-*-//////////////////////////////////////////////////////////////////
  2. //
  3. // Hoard: A Fast, Scalable, and Memory-Efficient Allocator
  4. //        for Shared-Memory Multiprocessors
  5. // Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery
  6. //
  7. // Copyright (c) 1998-2000, The University of Texas at Austin.
  8. //
  9. // This library is free software; you can redistribute it and/or modify
  10. // it under the terms of the GNU Library General Public License as
  11. // published by the Free Software Foundation, http://www.fsf.org.
  12. //
  13. // This library is distributed in the hope that it will be useful, but
  14. // WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19.  
  20. //////////////////////////////////////////////////////////////////////////////
  21. //
  22. // Note: This file was modified by Crystal Decisions in June 2002.
  23. //
  24. //////////////////////////////////////////////////////////////////////////////
  25.  
  26. #ifdef WIN32
  27.  
  28. #include <assert.h>
  29.  
  30. #include "arch-specific.h"
  31.  
  32. // How many iterations we spin waiting for a lock.
  33. enum 
  34.     SPIN_LIMIT = 100,           // user lock
  35.     SPIN_LIMIT_S = 16           // system lock
  36. };
  37.  
  38. static SYSTEM_INFO si;
  39. static DWORD numberOfProcessors = 1;
  40. static int unusedBits = 0;
  41. static DWORD flVirtualAlloc = MEM_COMMIT;
  42.  
  43. // TryEnterCriticalSection
  44. typedef BOOL (WINAPI *PROC_TryEnterCriticalSection)(LPCRITICAL_SECTION lpcs); 
  45. static PROC_TryEnterCriticalSection ptrTryEnterCriticalSection = NULL;
  46.  
  47. // SwitchToThread
  48. typedef BOOL (WINAPI *PROC_SwitchToThread)();
  49. static PROC_SwitchToThread ptrSwitchToThread = NULL;
  50.  
  51. static int initSystemInfo()
  52. {
  53.     // si and numberOfProcessors
  54.     GetSystemInfo(&si);  
  55.     numberOfProcessors = si.dwNumberOfProcessors;
  56.  
  57.     OSVERSIONINFO versionInfo;
  58.     versionInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
  59.     ::GetVersionEx( &versionInfo );
  60.  
  61.     // unusedBits
  62.     if ((versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  63.        (versionInfo.dwMajorVersion >= 5))  //Windows 2000
  64.     {
  65.         unusedBits = 2;         //The thread ID on Windows 2000 is always a multiple of 4.
  66.     }
  67.     else
  68.         unusedBits = 0;
  69.  
  70.     // ptrTryEnterCriticalSection
  71.     if ((versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  72.         (versionInfo.dwMajorVersion >= 4))  //Windows NT 4 or later
  73.     {
  74.         HMODULE hModule = ::GetModuleHandleA("KERNEL32.DLL");
  75.     
  76.         ptrTryEnterCriticalSection = (PROC_TryEnterCriticalSection)::GetProcAddress(hModule, "TryEnterCriticalSection"); 
  77.         ptrSwitchToThread = (PROC_SwitchToThread)::GetProcAddress(hModule, "SwitchToThread");
  78.     }
  79.  
  80.     // flVirtualAlloc
  81.     if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  82.         flVirtualAlloc = MEM_COMMIT | MEM_TOP_DOWN;
  83.     else
  84.         flVirtualAlloc = MEM_COMMIT;
  85.  
  86.     return 1;
  87. }
  88.  
  89. static const int blInitialized = initSystemInfo();
  90.  
  91. int hoardGetPageSize (void)
  92. {
  93.     return (int) (si.dwPageSize);
  94. }
  95.  
  96. int hoardGetNumProcessors (void)
  97. {
  98.     return numberOfProcessors;
  99. }
  100.  
  101. int hoardGetThreadID (void) 
  102. {
  103.     int tid = GetCurrentThreadId() >> unusedBits;
  104.     return tid;
  105. }
  106.  
  107. unsigned long hoardInterlockedExchange (unsigned long * oldval,
  108.                                         unsigned long newval)
  109. {
  110.     return InterlockedExchange ((long *) oldval, newval);
  111. }
  112.  
  113. void hoardCreateThread (hoardThreadType& t,
  114.                         void *(*function) (void *),
  115.                         void * arg)
  116. {
  117.     t = CreateThread (0, 0, (LPTHREAD_START_ROUTINE) function, (LPVOID) arg, 0, 0);
  118. }
  119.  
  120. void hoardJoinThread (hoardThreadType& t)
  121. {
  122.     WaitForSingleObject (t, INFINITE);
  123. }
  124.  
  125. void hoardSetConcurrency (int)
  126. {
  127. }
  128.  
  129. // hoardLockType
  130. void hoardLockInit (hoardLockType& mutex) 
  131. {
  132.     InterlockedExchange (&mutex, 0);
  133. }
  134.  
  135. void hoardLock (hoardLockType& mutex) 
  136. {
  137.     // A yielding lock (with an initial spin).
  138.     int i;
  139.     while (1) 
  140.     {
  141.         i = 0;
  142.         while (i < SPIN_LIMIT) 
  143.         {
  144.             if (mutex != LOCKED)
  145.             {
  146.                 if (InterlockedExchange (&mutex, LOCKED) == UNLOCKED) 
  147.                 {
  148.                     // We got the lock.
  149.                     return;
  150.                 }
  151.             }
  152.             i++;
  153.         }
  154.         
  155.         // Yield to other threads.
  156.         if (ptrSwitchToThread != NULL)
  157.             ptrSwitchToThread();
  158.         else
  159.             Sleep(0);
  160.     }
  161. }
  162.  
  163. void hoardUnlock (hoardLockType& mutex) 
  164. {
  165.     InterlockedExchange (&mutex, UNLOCKED);
  166. }
  167.  
  168. // hoardLockTypeS
  169. void hoardLockInit (hoardLockTypeS& mutex) 
  170. {
  171.     ::InitializeCriticalSection(&mutex);
  172. }
  173.  
  174. void hoardLock (hoardLockTypeS& mutex) 
  175. {
  176.     if (numberOfProcessors > 1)
  177.     {
  178.         int i = 0;
  179.         while (i < SPIN_LIMIT_S) 
  180.         {
  181.             if (ptrTryEnterCriticalSection(&mutex))  // We got the lock.            
  182.                 return;
  183.             i++;
  184.         }
  185.     }
  186.  
  187.     // Yield to other threads.
  188.     ::EnterCriticalSection( &mutex );
  189. }
  190.  
  191. void hoardUnlock (hoardLockTypeS& mutex) 
  192. {
  193.     ::LeaveCriticalSection( &mutex );
  194. }
  195.  
  196. void hoardYield (void) 
  197. {
  198.     if (ptrSwitchToThread != NULL)
  199.         ptrSwitchToThread();
  200.     else
  201.         Sleep(0);
  202. }
  203.  
  204. // I could possibly reduce the size of the following array to 8K, but then I have to add a
  205. // lock or something to synchronize the access. 
  206. static unsigned char segmentMasks[ 65536 ];     
  207. inline void markSegment( void* ptr, long size, unsigned char flag )
  208. {
  209.     assert( ( ( DWORD )ptr & 0xffff ) == 0 );
  210.     int index = ( ( DWORD )ptr >> 16 );
  211.     do
  212.     {
  213.         segmentMasks[ index ] = flag;
  214.         size -= 65536;
  215.         if ( size <= 0 )
  216.             break;
  217.         index ++;
  218.     } while ( 1 );
  219. }
  220.  
  221. bool hoardIsHoardPtr( void* ptr )
  222. {
  223.     int index = ( ( DWORD )ptr >> 16 );
  224.     return( segmentMasks[ index ] == 1 );
  225. }
  226.  
  227. void * hoardSbrk (long size)
  228. {
  229.     void * newMemory = ::VirtualAlloc (NULL, size, flVirtualAlloc, PAGE_READWRITE);
  230.     assert (newMemory);
  231.  
  232.     markSegment( newMemory, size, 1 );
  233.     return newMemory;
  234. }
  235.  
  236. void hoardUnsbrk (void * ptr, long size)
  237. {
  238.     markSegment( ptr, size, 0 );
  239.  
  240.     BOOL bResult = ::VirtualFree (ptr, 0, MEM_RELEASE);
  241.     assert (bResult);  
  242. }
  243.  
  244. #endif  // WIN32
  245.